package com.chenfan.process.config;

import feign.Client;
import feign.Request;
import feign.Response;
import feign.httpclient.ApacheHttpClient;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.http.MediaType;

import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * 转发本地Feign请求到测试环境，用于本地环境调试
 * @author wulg
 * @date 2021-07-09
 **/
@Configuration
@Profile(value={"local","dev"})
@ConditionalOnProperty(name="mock.server.enabled", havingValue = "true")
public class LocalFeignRequestForwardConfig {

    @Value("${mock.server.ip-address}")
    private String ipAddress;

    private final static String CONTENT_TYPE = "Content-Type";

    @Primary
    @Bean
    public Client loadBalancerFeignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory, HttpClient httpClient){
        return new LoadBalancerFeignClient(new ApacheHttpClient(httpClient), cachingFactory, clientFactory){

            @Override
            public Response execute(Request request, Request.Options options) throws IOException {
                URL url = new URL(request.url());
                String clientName = url.getHost();
                if(StringUtils.equals(clientName, "dingtalk-alarm")) {
                    return super.execute(request, options);
                }
                String requestUrl = url.getProtocol()+"://"+ipAddress+"/"+clientName.replace("-cloud-","_") + url.getFile();
                Request newRequest = Request.create(request.httpMethod(),requestUrl,request.headers(),request.body(),request.charset(),request.requestTemplate());
                Response response = super.getDelegate().execute(newRequest,options);;
                if(response.headers().containsKey(CONTENT_TYPE)) {
                    return response;
                }
                Map<String, Collection<String>> headers = new HashMap<>(response.headers().size());
                for(Map.Entry<String, Collection<String>> entry : response.headers().entrySet()) {
                    headers.put(entry.getKey(), entry.getValue());
                }
                headers.put(CONTENT_TYPE, Arrays.asList(MediaType.APPLICATION_JSON_VALUE));
                return Response.builder()
                        .request(response.request())
                        .headers(headers)
                        .body(response.body())
                        .status(response.status())
                        .reason(response.reason())
                        .build();
            }
        };
    }
}
